#pragma once
#include "ICommand.h"
#include <algorithm>
#include <cassert>

/*
* Class name: UpdateCommand
*
* This Class handles the update operation of TaskLine to update one of the following attributes:
* Title, Location, Description, People, Priority, IsFinishedStatus, StartTime, StartDate, EndTime, EndDate.
* 
* An instance of UpdateCommand is initialized with a valid user input string, during which parser function and its helpers
* will first check whether all components of the string input are valid and then set the previousTask and newTask pointers.
* A meaningful error message will be thrown if any part of the parser fails.
* 
* UpdateCommand only has two APIs:
* Execute() for executing\redoing the update, i.e., updating the pointer in storage with newTask pointer.
* Unexecute() for undoing the update, i.e., updating the pointer in storage with previousTask pointer.
*
* @author A0105475H
*/


//@author A0105475H

class UpdateCommand :
	public ICommand
{
public:
	UpdateCommand(string);
	~UpdateCommand(void);

	string Execute();
	string Unexecute();

private:
	FloatingTask* previousTask;
	FloatingTask* newTask;
	Storage::updateType attributeType;
	int index;
	Storage* storage;
	
	enum taskType{
		floatingTask, deadlineTask, timedTask
	};

	void parser(string);

	//helpers: main components for parser
	void checkInput(string&);
	void checkIndex(string&);
	void checkAttributeType(string&);
	void checkAttributeValue(string&);
	void updateAttribute(string);

	//helpers: checking input string
	taskType determineTaskType(FloatingTask*);
	Storage::updateType determineAttributeType(string);
	void removeWhiteSpaces(string&);

	//helpers: validating the attribute inputs
	bool isValidStringPriority(string);
	bool isValidIntPriority(string);

	bool isValidStringStatus(string);
	bool isValidIntStatus(string);

	bool isValidDate(string);
	bool normalizeAndValidate(int, int, int);
	bool isValidDateFormat2(string);
	
	bool isValidTime(string);
	bool isValidTimeFormat1(string);
	bool isValidTimeFormat2(string);

	bool isLaterThan(time_t, time_t);
	time_t parseTime(time_t, string);
	time_t parseDate(time_t, string);
	bool setMonth(char*, int&);

	//helpers: updating the relevant attributes
	void initializePreviousNewTask();

	void updateTitle(string);
	void updateLocation(string);
	void updateDescription(string);
	void updatePerson(string);
	void updatePriority(int);
	void updateStatus(int);
	void updatePriority(string);
	void updateStatus(string);

	void updateFloatingStartTime(string);  //converted to a timed task
	void updateDeadlineStartTime(string);  //converted to a timed task
	void updateTimedStartTime(string);

	void updateFloatingStartDate(string);   //converted to a timed task
	void updateDeadlineStartDate(string);   //converted to a timed task
	void updateTimedStartDate(string);

	void updateFloatingEndTime(string);   //converted to a deadline task
	void updateDeadlineEndTime(string);
	void updateTimedEndTime(string);
	
	void updateFloatingEndDate(string);   //converted to a deadline task
	void updateDeadlineEndDate(string);
	void updateTimedEndDate(string);
};

